import log from "./logger";
import * as fs from 'fs';
import config from "./config";
import * as path from "path";
import {axios, FormData, iconv} from "../node-test";
import {RadarPointRecordUpdateCO} from "./interface";

function uploadOss(pointsFileName: string): Promise<string> {
    return new Promise((resolve, reject) => {
        const data = new FormData();
        data.append('contractFile', fs.createReadStream(pointsFileName), pointsFileName);
        axios.post(
            config.host + '/api/account/oss/oss2',
            data,
            {headers: data.getHeaders()}
        ).then(function (response: any) {
            resolve(response.data.data);
        }).catch(function (e) {
            log.error(e.message)
            reject("uploadOss2 error");
        });
    });
}

function getPointStr(dir: string, file: string) {
    file.replace("Data", "Points")
    const pointsData = fs.readFileSync(path.join(dir, file));
    return iconv.decode(pointsData, 'gbk');
}

function writePointFile(pointsStr: any, dir: string, pointsFileName: string) {
    let split = pointsStr.split("\r\n");
    const plyHeader = `ply\nformat ascii 1.0\nelement vertex ${Math.floor(split.length / 5)}\nproperty float x\nproperty float y\nproperty float z\nend_header\n`;
    // let plyFileName = path.join(dir, pointsFileName + ".ply");
    let plyFileName = pointsFileName + ".ply";
    fs.writeFileSync(plyFileName, plyHeader);
    for (let i = 0; i < split.length; i += 5) {
        let point = split[i].replace("(", "").replace(")", "").split(",");
        if (point[0] && point[1]) {
            const pointLine = `${point[0]} ${point[1]} ${point[2]}\n`;
            fs.appendFileSync(plyFileName, pointLine);
        }
    }
    log.info("写入ply文件完成")
}

function formatDateTime(filename: string) {

// Regular Expression to match the pattern YYYYMMDD_HH
    const datePattern = /(\d{4})(\d{2})(\d{2})_(\d{2})/;

// Extract the date and time parts from the filename
    const match = filename.match(datePattern);

    if (match) {
        // Construct the date and time string in the format "YYYY-MM-DD HH:00:00"
        const year = match[1];
        const month = match[2];
        const day = match[3];
        const hour = match[4];
        return `${year}-${month}-${day} ${hour}:00:00`;
    } else {
        console.log("No date and time found in the filename.");
    }
}

async function updateData(file: string, str: any, url: string) {
    //{
    //    "density" : 1,
    //    "volume" : 117392.08917602482,
    //    "weight" : 117392.08917602482
    // }
    let parse = JSON.parse(str);
    let data: RadarPointRecordUpdateCO = {
        density: parse.density.toString(),
        platformId: config.platformId,
        platformName: config.platformName,
        radarPointCode: config.deviceName,
        scanTime: formatDateTime(file),
        url: url,
        volume: parse.volume.toString(),
        weight: parse.weight.toString()
    }
    let axiosResponse: any = await axios.post(config.host + '/api/weigh/external/radarPointRecord/update', data);
    log.info("axiosResponse:", axiosResponse.data);
    if (axiosResponse.data.code !== '0000') {
        throw axiosResponse.data.toString();
    }
}

async function traverseDirectorySyncSorted(dir: string) {
    // 读取目录中的所有文件/目录并排序
    let files = fs.readdirSync(dir);
    let fileList: any[] = [];
    for (let file of files) {
        // log.info("filename:", filename)
        if (file.startsWith("Data") && file.endsWith("txt")) {
            fileList.push(file);
        }
    }
    // 只获取前5个文件或目录
    let fileSlice = fileList.sort().slice(0, 1);

    for (const file of fileSlice) {
        // 获取完整的文件/目录路径
        const fullPath = path.join(dir, file);
        // 获取文件/目录的状态信息
        const stat = fs.statSync(fullPath);

        if (stat.isDirectory()) {
            // 如果是目录，则递归遍历
            // console.log(`Directory: ${fullPath}`);
            // traverseDirectorySyncSorted(fullPath);
        } else {
            // 如果是文件，就处理文件
            log.info(`File: ${fullPath}`);
            // 同步读取文件内容
            const iconv = require('iconv-lite');
            const data = fs.readFileSync(fullPath);
            // const data = fs.readFileSync(fullPath, 'ascii');
            // 将文件内容按行分割为数组
            const str = iconv.decode(data, 'gbk');
            // log.info(str);
            // 找到同名的点云文件；
            let pointsFileName = file.replace("Data", "Points");
            let pointsStr = getPointStr(dir, pointsFileName);
            // console.log(pointsStr);
            writePointFile(pointsStr, dir, pointsFileName);
            // 上传ply文件
            let url = await uploadOss(pointsFileName + ".ply")
            // 上传服务器记录数据
            await updateData(file, str, url)
            // 删除点云文件、ply文件，data文件
            fs.rmSync(path.join(dir, pointsFileName));
            fs.rmSync(pointsFileName + ".ply");
            fs.rmSync(path.join(dir, file));
            log.info("删除完成");
        }
    }
}

class KemenRadarWorker {
    init() {
        this.collection();
        // setInterval(() => {
        //     this.collection();
        // }, 1000 * 60)
    }

    async collection() {
        try {
            // await traverseDirectorySyncSorted('D:\\lw');
            let dir = '';
            if (config.deviceName === 'kemen_radar3') {
                dir = '\\\\192.168.2.158\\PointsExport';
            } else if (config.deviceName === 'kemen_radar4') {
                dir = '\\\\192.168.2.205\\PointsExport';
            }
            await traverseDirectorySyncSorted(dir);
        } catch (e) {
            log.error(e)
        }
        // 延时5分钟循环调用
        setTimeout(() => {
            log.info("延时时间到，开始新的采集")
            this.collection();
        }, 1000 * 60 * 5)
    }
}

const kemenRadarWorker = new KemenRadarWorker();
export default kemenRadarWorker;